﻿using System;
using System.Collections.Generic;
using Layers;

namespace Layers.History
{

    internal class ArrayTimeHistoryCursor<E> : IHistCursor<DateTime, E> where E:ITimeSerial
    {
        private ArrayTimeHistory<E> _history;
        private int _index;

        public ArrayTimeHistoryCursor(ArrayTimeHistory<E> history)
        {
            _history = history;
            _index = -1;
        }

        #region ICursor<E> Members

        public E Current
        {
            get
            {
                return _history.InnerList[_index];
            }
            set
            {
                _history.InnerList[_index] = value;
            }
        }

        object ICursor.Current
        {
            get { return _history.InnerList[_index]; }
            set { _history.InnerList[_index] = (E)value; }
        }

        public bool MoveNext()
        {
            throw new NotImplementedException();
        }

        public void Insert()
        {
            _history.InsertAt(_index);
        }

        public void Remove()
        {
            _history.RemoveAt(_index);
        }

        public int Seek(SeekPos sp, int offset)
        {
            switch (sp)
            {
                case SeekPos.BeforeFirst: _index = -1; break;
                case SeekPos.First: _index = _history.Count > 0 ? offset : -1; break;
                case SeekPos.Last: _index = _history.Count - 1 + offset; break;
                case SeekPos.AfterLast: _index = _history.Count; break;
            }
            return _index;
        }

        public DateTime CurrentStamp
        {
            get { return _history.InnerList[_index].TimeStamp; }
            set { _index = _history.IndexOf(value); }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            
        }

        #endregion

        #region IEnumerator Members

        object System.Collections.IEnumerator.Current
        {
            get { return this.Current; }
        }

        public void Reset()
        {
            _index = -1;
        }

        #endregion
    

}

    public class ArrayTimeHistory<E> : ITimeHistory<E> where E:ITimeSerial
    {
        private IList<E> _innerList;

        #region IHistory<DateTime,E> Members

        public int Count
        {
            get { return _innerList.Count; }
        }

        public Window<DateTime> Range
        {
            get {
                Window<DateTime> wnd = new Window<DateTime>();
                if (Count > 0)
                {
                    wnd.Begin = _innerList[0].TimeStamp;
                    wnd.End = _innerList[_innerList.Count - 1].TimeStamp;
                }
                return wnd;
            }
        }

        public int IndexOf(DateTime ts)
        {
            for (int i = 0; i < _innerList.Count; i++)
                if (_innerList[i].TimeStamp.Equals(ts))
                    return i;
            return -1;
        }

        internal IList<E> InnerList { get { return _innerList; } }

        internal void InsertAt(int index)
        {
            _innerList.Insert(index, default(E));
        }
        internal void RemoveAt(int index)
        {
            _innerList.RemoveAt(index);
        }

        public IList<Window<DateTime>> Windows
        {
            get {
                return Factory.NewObsList<Window<DateTime>>(
                    new Window<DateTime>[] { Range });

            }
        }

        public IHistCursor<DateTime, E> GetCursor()
        {
            return new ArrayTimeHistoryCursor<E>(this);
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public IEnumerator<E> GetEnumerator()
        {
            return _innerList.GetEnumerator();
        }

        #endregion
    }
}